package com.mrogrape.net;

import java.net.InetAddress;
import java.net.UnknownHostException;

import com.mrogrape.util.StringUtils;


/**
 * 包含网络编程中比较常用的实用方法.
 * @author Ice Spring
 * @version 
 */
public class NetUtils {

	/**
	 * 判断一个字符串是否为IP地址。
	 * 
	 * 判断基于以下准则
	 * <ul>
	 * <li>不为空（这包括空指针和空串）
	 * <li>由被“.”分割的四个大小在0~255之间的数字组成
	 * </ul>
	 * @param ipAddress 需要判断的字符串
	 * @return 是否是IP地址
	 */
	public static boolean isIpAddress(String ipAddress){
		//判断是否为空,为空则为假
		if(StringUtils.isEmpty(ipAddress)){
			return false;
		}

		String strs[] = ipAddress.replace(".", ";").split(";");

		//如果经过"."分割后不足四位，返回假
		if(strs.length!=4){
			return false;
		}
		int[] add = new int[4];
		try{
			for(int i = 0 ; i < 4 ; i ++){
				add[i] = Integer.parseInt(strs[i]);
				if(add[i]<0||add[i]>255){
					return false;
				}
			}
		}catch(Exception e){
			return false;
		}

		return true;
	}

	/**
	 * 获取原始数据类型的IP地址：一个长度为4的byte数组，高位存在于getAddress()[0]中
	 * @param ipAddress 字符串形式的ip地址
	 * @return 原始IP地址
	 */
	public static byte[] getIpByte(String ipAddress){
		byte[] ip = new byte[4];
		if(!NetUtils.isIpAddress(ipAddress)){
			throw new IllegalArgumentException(NetUtils.ERROR_EMPTY_PARAM);
		}
		String strs[] = ipAddress.replace(".", ";").split(";");
		for(int i = 0; i < 4 ; i++){
			ip[i] = (byte) Integer.parseInt(strs[i]);
		}
		return ip;
	}

	private static final String ERROR_EMPTY_PARAM = "Parameter can not be empty.";

	/**
	 * 根据原始类型的IP地址获取其字符串表示形式
	 * @param ip 原始IP地址：必须是一个长度为4的byte数组，高位存在于getAddress()[0]中
	 * @return 原始IP地址的字符串表示形式<b>如果转换失败会返回空串<b>
	 */
	public static String getIpStr(byte[] ip){
		if(ip.length!=4) {
			return StringUtils.BLANK;
		}
		String str = StringUtils.BLANK;
		try {
			InetAddress net = InetAddress.getByAddress(ip);
			str = net.getHostAddress();
		} catch (UnknownHostException e) {
			return StringUtils.BLANK;
		}
		return str;
	}

	/**
	 * 根据一个表示IP地址的字符串返回其对应的InetAddress对象
	 * @param ipAdd IP地址的字符串表示形象
	 * @return 对应的InetAddress对象，如果发生错误则返回空
	 */
	public static InetAddress getInetAddress(String ipAdd){
		if(ipAdd == null || !NetUtils.isIpAddress(ipAdd)){
			return null;
		}
		byte[] ip = NetUtils.getIpByte(ipAdd);
		try {
			return InetAddress.getByAddress(ip);
		} catch (UnknownHostException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 根据Ip地址的原始表示形式返回对应的InetAddress对象。
	 * @param ipadd 以byte数组表示的IP地址。
	 * @return InetAddress 对象
	 */
	public static InetAddress getInetAddress(byte[] ipadd){
		try {
			return InetAddress.getByAddress(ipadd);
		} catch (UnknownHostException e) {
			return null;
		}
	}

}
